<?php
//-------------------------------------------------------------------------
// OVIDENTIA http://www.ovidentia.org
// Ovidentia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//-------------------------------------------------------------------------
/**
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
 * @copyright Copyright (c) 2006 by CANTICO ({@link http://www.cantico.fr})
 */
//include_once 'base.php';


require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/item.class.php';

/**
 * Constructs a Widget_Layout.
 *
 * @param string $id	The item unique id.
 * @return Widget_Layout
 */
function Widget_Layout($id = null)
{
	return new Widget_Layout($id);
}

/**
 * The Widget_Layout class is the base class of geometry managers.
 * 
 * A Widget_Layout object is used to specifiy the way items contained in a
 * {@link Widget_ContainerWidget} are laid out on the page.
 * A layout can contain {@link Widget_Widget} objects or other Widget_Layout objects
 * so that it is possible to combine several layouts to design a complex dialog.
 */
class Widget_Layout extends Widget_Item implements Widget_Displayable_Interface
{
	private $_items;
	private $_vspacing 	= null;
	private $_hspacing 	= null;
	private $_valign 	= null;
	private $_halign 	= null;
	private $_initScript;
	private $_parent;
	
	private $_sortable	= false;
	
	const DEFAULT_SPACING = 8;

	const DEFAULT_VERTICAL_ALIGN = 'top';		// top, middle, bottom
	const DEFAULT_HORIZONTAL_ALIGN = 'left';	// left, center, right
	
	

	/**
	 * @param string $id	The item unique id.
	 * @return Widget_Layout
	 */
	public function __construct($id = null)
	{
		assert('is_string($id) || is_null($id); /* The id parameter must be a string or null */');
		$this->_items = array();
		parent::__construct($id);
		$this->setInitScript('');
		$this->_canvasOptions = Widget_Item::Options();
	}

	public function setInitScript($script)
	{
		$this->_initScript = $script;
	}


	/**
	 * Sets the parent of the layout.
	 *
	 * @param Widget_ContainerWidget|Widget_Layout $parent
	 */
	public function setParent($parent)
	{
//		assert('is_null($parent) || $parent instanceof Widget_ContainerWidget || $parent instanceof Widget_Layout; /* The parent parameter must be null, a Widget_ContainerWidget object or a Widget_Layout object */');
		$this->_parent = $parent;
		foreach (array_keys($this->_items) as $key)
		{
			$item = $this->_items[$key];
//			if ($item instanceof Widget_Widget) {
				$item->setParent($parent);
//			} else {
//				$item->_parent = $parent;
//			}
		}
	}

	/**
	 * Returns the parent of the layout.
	 *
	 * @return Widget_Item
	 */
	public function getParent()
	{
		return $this->_parent;
	}


	/**
	 * Adds $item to this layout in a manner specific to the layout.
	 *
	 * @param Widget_Item $item
	 * @return Widget_Layout
	 */
	public function addItem(Widget_Displayable_Interface $item)
	{
		assert('is_null($item->getParent()); /* The item must not already have a parent */');
		$this->_items[$item->getId()] = $item;
		$item->setParent($this->getParent());
		return $this;
	}


	/**
	 * Sets whether the each field of the layout is mandatory or not.
	 * 
	 * If the field is inside a dialog, the dialog will report an error to
	 * the user if he did not fill in the field on submit.
	 * This method returns the widget itself so that other methods can be chained.
	 * 
	 * @param boolean $mandatory
	 * @param string $message		The message displayed by the dialog if the field is left empty.
	 * @return Widget_Widget
	 */
	public function setMandatory($mandatory = true, $message = '')
	{
		assert('is_bool($mandatory); /* The "mandatory" parameter must be a boolean. */');
		assert('is_string($message); /* The "message" parameter must be a string. */');
		
		$items = $this->getItems();
		foreach($items as $item){
			$item->setMandatory($mandatory, $message);
		}
		return $this;
	}
	


	/**
	 * Returns an array of the items managed by the layout.
	 * 
	 * @return array		An array of the items managed by the layout.
	 */
	public function getItems()
	{
		return $this->_items;
	}


	/**
	 * Returns the item with identifier $id managed by the layout.
	 * 
	 * @return Widget_Item
	 */
	public function getItem($id)
	{
		return $this->_items[$id];
	}


	/**
	 * Sets the spacing between items in the layout.
	 *
	 * @param 	int		$spacing
	 * @param	string	$unit
	 * @param	int		$vspace
	 * @param	string	$vunit
	 * @return Widget_Layout
	 */
	public function setSpacing($spacing, $unit = null, $hspace = null, $hunit = null)
	{
		assert('is_numeric($spacing); /* The spacing parameter must be an integer */');
		$this->setVerticalSpacing($spacing, $unit);
		if (null === $hspace)
		{
			$hspace = $spacing;
			$hunit = $unit;
		}
		
		$this->setHorizontalSpacing($hspace, $hunit);
		
		return $this;
	}
	
	
	/**
	 * Sets the horizontal spacing (in pixels) between items in the layout.
	 *
	 * @param int	$spacing
	 * @return Widget_Layout
	 */
	public function setHorizontalSpacing($spacing, $unit = null)
	{
		assert('is_numeric($spacing); /* The spacing parameter must be an integer */');
		$this->_canvasOptions->horizontalSpacing($spacing, $unit);
		return $this;
	}
	
	
	/**
	 * Sets the vertical spacing (in pixels) between items in the layout.
	 *
	 * @param int	$spacing
	 * @return Widget_Layout
	 */
	public function setVerticalSpacing($spacing, $unit = null)
	{
		assert('is_numeric($spacing); /* The spacing parameter must be an integer */');
		$this->_canvasOptions->verticalSpacing($spacing, $unit);
		return $this;
	}

		


	/**
	 * Return the horizontal spacing (in pixels) between items in the layout.
	 *
	 * @return int
	 */
	public function getHorizontalSpacing()
	{
		return $this->_canvasOptions->horizontalSpacing();
//		return $this->_hspacing;
	}
	
	/**
	 * Return the vertical spacing (in pixels) between items in the layout.
	 *
	 * @return int
	 */
	public function getVerticalSpacing()
	{
		return $this->_canvasOptions->verticalSpacing();
//		return $this->_vspacing;
	}
	

	/**
	 * Sets the vertical align property for layout items
	 *
	 * @param string	$align		"top", "middle" or "bottom"
	 * @return Widget_Layout
	 */
	public function setVerticalAlign($align) {
//		assert('in_array($align, array("top", "middle", "bottom")); /* The align parameter must be "top", "middle" or "bottom" */');
		$this->_canvasOptions->verticalAlign($align);
//		$this->_valign = $align;
		return $this;
	}
	
	
	/**
	 * @return string
	 */
	public function getVerticalAlign() {
		return $this->_canvasOptions->verticalAlign();
//		return $this->_valign;
	}
	
	/**
	 * Sets the horizontal align property for layout items
	 *
	 * @param string	$align		"left", "center" or "right"
	 * @return Widget_Layout
	 */
	public function setHorizontalAlign($align) {
		assert('in_array($align, array("left", "center", "right")); /* The align parameter must be "left", "center" or "right" */');
		$this->_canvasOptions->horizontalAlign($align);
//		$this->_halign = $align;
		return $this;
	}
	
	/**
	 * @return string
	 */
	public function getHorizontalAlign() {
		return $this->_canvasOptions->horizontalAlign();
//		return $this->_halign;
	}


	/**
	 * Set sortable attribute, default true
	 * @param	bool	[$param]
	 * 
	 * @return	Widget_Layout
	 */ 
	public function sortable($param = true) {
		$this->_sortable = $param;
		
		return $this;
	}


	/**
	 * Dumps the item for debugging purpose.
	 *
	 * @param string	$prefix
	 * @param bool		$standalone
	 * @return string
	 * @ignore
	 */
	public function dump($prefix = '', $standalone = true)
	{
		if ($standalone) {
			$dumpString = parent::dump($prefix) . "\n";
		} else {
			$dumpString = ' [' . get_class($this) . '("<b>' . $this->getId() . '</b>")]' . "\n";
		}
		$items = $this->getItems();
		$nbItems = count($this->getItems());
		for ($i = 0; list(,$item) = each($items); $i++) {
			if ($i > 0) {
				$dumpString .= "\n";
			}
			$dumpString .= $item->dump($prefix . '&#9474;    ');
		}
		return $dumpString;
	}


	public function getClasses()
	{
		$classes = parent::getClasses();
		$classes[] = 'widget-layout';
		
		if ($this->_sortable) {
			$classes[] = 'widget-sortable';
		}
		
		return $classes;
	}
	
	
	public function getCanvasOptions()
	{
		return $this->_canvasOptions;

//		if (null === $this->getVerticalAlign()
//			&& null === $this->getHorizontalAlign()
//			&& null === $this->getVerticalSpacing()
//			&& null === $this->getHorizontalSpacing()) {
//			return null;
//		}
//	
//	
//		require_once dirname(__FILE__).'/canvasoptions.class.php';
//		$options = new Widget_CanvasOptions();
//		
//		$options->VerticalSpacing($this->getVerticalSpacing());
//		$options->HorizontalSpacing($this->getHorizontalSpacing());
//		$options->horizontalAlign($this->getHorizontalAlign());
//		$options->verticalAlign($this->getVerticalAlign());
//		
//		return $options;
	}
	

	public function display(Widget_Canvas $canvas)
	{
		$items = array();
		foreach($this->getItems() as $item) {
			$items[] = $item;
		}
		return $canvas->defaultLayout($this->getId(), $this->getClasses(), $items, $this->getCanvasOptions());
	}

}

